package com.game.net;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NettyServer extends Thread {
    Logger log = LoggerFactory.getLogger(getClass());

    private int portNumber;

    private String address;

    private ChannelInitializer<SocketChannel> initializer;

    private ServerBootstrap b;

    public NettyServer(int portNumber, ChannelInitializer<SocketChannel> initializer) {
        this(null, portNumber, initializer);
    }

    public NettyServer(String address, int portNumber, ChannelInitializer<SocketChannel> initializer) {
        super("netty-server-" + portNumber);
        this.address = address;
        this.portNumber = portNumber;
        this.initializer = initializer;
    }




    public void run() {
        NioEventLoopGroup nioEventLoopGroup1 = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() + 1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ChannelFuture f;
            this.b = new ServerBootstrap();
            this.b.group((EventLoopGroup)nioEventLoopGroup1, (EventLoopGroup)workerGroup);
            this.b.channel(NioServerSocketChannel.class);
            ((ServerBootstrap)this.b.childHandler((ChannelHandler)this.initializer).childOption(ChannelOption.SO_KEEPALIVE, Boolean.valueOf(true))
                    .option(ChannelOption.SO_BACKLOG, Integer.valueOf(4096)))
                    .handler((ChannelHandler)new LoggingHandler(LogLevel.INFO));
            if (this.address != null) {
                f = this.b.bind(this.address, this.portNumber).sync();
                this.log.info("Server started on address " + this.address + ", port " + this.portNumber);
            } else {
                f = this.b.bind(this.portNumber).sync();
                this.log.info("Server started on port " + this.portNumber);
            }
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            this.log.error("\nnet server start error...\n", e);
        } finally {
            nioEventLoopGroup1.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
